﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Linq;
using System.Linq;
using SSTU.Model;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Data.Linq;
using SSTU.Management.Module;
using System.Threading;

namespace SSTU.Data
{
	public class SstuDataContext : DataContext
	{
		private static readonly object DbSyncRoot = new object();
		public const string ConnectionString = "isostore:/sstu.sdf";

		protected SstuDataContext()
			: base(ConnectionString)
		{
			Faculties = GetTable<FacultyEntity>();
			Groups = GetTable<GroupEntity>();
			Classes = GetTable<ClassEntity>();
			GroupToClassMap = GetTable<GroupToClassMapEntity>();
		}

		/// <summary>
		/// Gets the faculties.
		/// </summary>
		public Table<FacultyEntity> Faculties { get; private set; }

		/// <summary>
		/// Gets the groups.
		/// </summary>
		public Table<GroupEntity> Groups { get; private set; }

		/// <summary>
		/// Gets the classes.
		/// </summary>
		public Table<ClassEntity> Classes { get; private set; }

		/// <summary>
		/// Gets the group to class map.
		/// </summary>
		public Table<GroupToClassMapEntity> GroupToClassMap { get; private set; }

		/// <summary>
		/// Initializes the data context and the local database at the device, asynchronously.
		/// </summary>
		public static void InitializeAsync()
		{
			lock (DbSyncRoot)
			{
				ThreadPool.QueueUserWorkItem(o =>
				{
					lock (DbSyncRoot)
					{
						Initialize();
					}
				});
			}
		}

		/// <summary>
		/// Initializes the data context and the local database at the device/
		/// </summary>
		private static void Initialize()
		{
			using (SstuDataContext dataContext = new SstuDataContext())
			{
				if (!dataContext.DatabaseExists())
				{
					dataContext.CreateDatabase();
					dataContext.SubmitChanges();
					var updater = dataContext.CreateDatabaseSchemaUpdater();
					updater.DatabaseSchemaVersion = SstuApp.CurrentAppVersion;
					updater.Execute();
				}
				else
				{
					try
					{
						var updater = dataContext.CreateDatabaseSchemaUpdater();
						if (updater.DatabaseSchemaVersion < SstuApp.AppVersion_01000003)
						{
							updater.AddTable<ClassEntity>();
							updater.AddTable<GroupToClassMapEntity>();
						}
						updater.DatabaseSchemaVersion = SstuApp.CurrentAppVersion;
						updater.Execute();
					}
					catch (Exception)
					{
						dataContext.DeleteDatabase();
						dataContext.SubmitChanges();
						dataContext.CreateDatabase();
						dataContext.SubmitChanges();
						var updater = dataContext.CreateDatabaseSchemaUpdater();
						updater.DatabaseSchemaVersion = SstuApp.CurrentAppVersion;
						updater.Execute();
					}
				}
			}
		}

		/// <summary>
		/// Creates the data context.
		/// </summary>
		public static SstuDataContext Create()
		{
			lock (DbSyncRoot)
			{
				var dataContext = new SstuDataContext();
				return dataContext;
			}
		}
	}
}
